using System;
using System.Collections.Generic;

namespace LannyPractiseCode
{
    public class SingleLinkedList
    {
        private HeroNode headNode;
        public SingleLinkedList()
        {
            headNode=new HeroNode(0,"","");
        }

        // 末尾添加
        public void Add(HeroNode heroNode)
        {
            //节点不能动，因此我们需要一个辅助的便利tempNode
            HeroNode temp=headNode;
            while(true)//遍历，找到最后
            {
                if(temp.NextNode==null)
                    break;
                //如果没有最后，temp后移
                temp=temp.NextNode;
            }
            //推出while之后，temp指向了链表的最后
            //最后将这个节点的next指向新的节点
            temp.NextNode=heroNode;
        }
        // 根据Id排名指定到某个位置
        public void AddByOrder(HeroNode heroNode)
        {
            HeroNode temp=headNode;
            Boolean flag=false;
            while(true)
            {
                if(temp.NextNode==null)
                    break;//添加到最后了
                //位置找到了。注意：记住要在【tempNode.NextNode.Id】跟tempNode比。
                if(temp.NextNode.Id>heroNode.Id) 
                    break;
                else if(temp.NextNode.Id==heroNode.Id)
                {
                    flag=true; //存在相同编号
                    break;
                }
                temp=temp.NextNode;
            }
            if(flag)
                System.Console.WriteLine("已经存在，不能添加！");
            else
            {
                //插入到链表中，tempNode的后面
                heroNode.NextNode=temp.NextNode; //开始改变指针
                temp.NextNode=heroNode;
            }
        }

        // 更新节点
        public void UpdateNode(HeroNode newNode)
        {
            if(headNode.NextNode==null)
            {
                System.Console.WriteLine("");
                return;
            }
            HeroNode temp=headNode;//辅助节点
            Boolean flag=false;//是否找到节点
            while(true)
            {
                if(temp.Id==newNode.Id)
                {
                    //找到节点
                    flag=true;
                    break;
                }
                temp=temp.NextNode;//没找到，继续下一个。
            }

            if(flag)
            {
                temp.Name=newNode.Name;
                temp.NickName=newNode.NickName;
            }
            else
                System.Console.WriteLine("没有需要修改的项...");
        }

        //删除节点
        public void DeleteNode(int Id)
        {
            if(headNode.NextNode==null)
                System.Console.WriteLine("链表为空，无法删除。");
              
            HeroNode temp=headNode;
            bool flag=false; //标记是否找到待删除节点
            while(true)
            {
                if(temp.NextNode==null)
                {
                    break;//已经到最后
                }

                if(temp.Id==Id)
                {
                    flag=true;
                    break;
                }
                temp=temp.NextNode;
            }

            if(flag)
            {
                temp.NextNode=temp.NextNode.NextNode;
            }
            else
            {
                System.Console.WriteLine("没有节点可删除！");
            }
        }

        //*******************面试题**************
        //获取有效结点数
        public int GetNodesLength(HeroNode heroNode)
        {
            HeroNode curNode=headNode.NextNode;
            int iLength=0;
            while(true)
            {
                if(curNode!=null)
                {
                    iLength++;
                    curNode=curNode.NextNode;
                }
                else 
                    break;
            }

            return iLength;
        }

        //新浪面试:获取倒数第Index的节点
        //1.编写一个方法，接收head节点，同时接收- -个index
        //2.index 表示是倒数第index个节点
        //3.先把链表从头到尾遍历，得到链表的总的长度getLength
        //4.得到size后，我们从链表的第-个开始遍历(size-index)个,就可以得到
        //5.如果找到了,则返回该节点，否则返回nu1ll
        public HeroNode GetLastIndexNode(HeroNode node,int index)
        {
            if(node.NextNode==null)
                return null;
            int iLength=GetNodesLength(node);
            if(index<0 || index>iLength)
                return null;

            HeroNode curNode=node.NextNode;
            for(int i=0;i<iLength-index;i++)
                curNode=curNode.NextNode;

             return curNode;   
                
        }

        //获取头节点
        public HeroNode GetHeadNode()
        {
            return headNode;
        }
        public void Display()
        {
            //节点不能动，因此我们需要一个辅助的便利tempNode
            HeroNode temp=headNode.NextNode;
            while(true)//遍历，找到最后
            {
                if(temp==null)
                    break;
                else
                {
                    System.Console.WriteLine(temp);
                    temp=temp.NextNode;
                }
                    
            }
        }
    }
}